package cn.tedu.project.oa.base.interceptor;


import cn.tedu.project.oa.base.exception.TokenAuthException;
import cn.tedu.project.oa.base.response.StatusCode;
import cn.tedu.project.oa.base.util.TokenUtil;
import cn.tedu.project.oa.sys.common.ResponseCodeConstants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenUtil tokenUtil;

    /**
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     * @descrption 预处理方法，在请求实际处理之前进行调用
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws RuntimeException {
        log.debug("进入拦截器预处理方法................");

        // 获取请求头中的token
        String token = request.getHeader("Authorization");
        log.debug("拦截器中获取的token：{}", token);

        // 检查是否是静态资源或非方法请求，直接放行
        if (!(handler instanceof HandlerMethod)) {
            log.debug("不是映射的方法，可以直接访问！");
            return true;
        }

        // 如果 token 为空，抛出异常
        if (StringUtils.isEmpty(token)) {
            log.debug("token为空，访问被拒！");
            throw new TokenAuthException(ResponseCodeConstants.TOKEN_INVALIDED, "会话已过期,请重新登录");
        }

        // 检查 token 格式是否有效
        if (token.split("\\.").length != 3) {
            log.debug("无效的 token 格式，访问被拒！");
            throw new TokenAuthException(ResponseCodeConstants.TOKEN_INVALIDED, "会话已过期,请重新登录");
        }

        // 校验 token 是否过期
        if (tokenUtil.isExpired(token)) {
            log.debug("token过期");
            throw new TokenAuthException(ResponseCodeConstants.TOKEN_EXPIRED, "会话已过期,请重新登录");
        } else {
            log.debug("token验证通过：{}", token);
            return true;
        }
    }

}
